﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Krilib.Data;
using System.Xml.Serialization;
namespace Krile.Data
{
    public class TabData : IDisposable
    {
        [XmlIgnore()]
        private Forms.MainForm.Controls.XTab.XTabTLItem parentTabItem;

        [XmlIgnore()]
        public Forms.MainForm.Controls.XTab.XTabTLItem Parent
        {
            get { return parentTabItem; }
            set
            {
                parentTabItem = value;
                if (parentTabItem != null && nameBuffer != null)
                {
                    parentTabItem.Name = nameBuffer;
                    nameBuffer = null;
                }
            }
        }

        public TabData()
        {
            this.Locked = false;
            parentTabItem = null;
        }

        public TabData(Forms.MainForm.Controls.XTab.XTabTLItem parent)
        {
            this.Locked = false;
            parentTabItem = parent;
        }

        Cores.StatusManager.XStatusRegisteredCallback registered = null;
        Cores.StatusManager.XStatusRegisteredCallback removed = null;
        List<XStatus> containStatus = null;

        public event EventHandler ContainStatusChanged;

        internal XStatus[] ContainStatuses
        {
            get
            {
                if (containStatus != null)
                    return containStatus.ToArray();
                else
                    return null;
            }
        }

        public void InitTabData()
        {
            registered = new Cores.StatusManager.XStatusRegisteredCallback(StatusManager_RegistStatus);
            removed = new Cores.StatusManager.XStatusRegisteredCallback(StatusManager_RemoveStatus);
            containStatus = new List<XStatus>();
            Core.StatusManager.OnXStatusRegistered += registered;
            Core.StatusManager.OnXStatusRemoved += removed;
            containStatus.AddRange(Core.StatusManager.ExtractXStatuses(ContainSearchData));
            containStatus.Sort(new Comparison<XStatus>(Cores.StatusManager.StatusServerSorts.StatusSortComparison));
            Cores.StatusManager.StatusServerSorts.StatusSortComparisonUpdated += new Action(StatusServerSorts_StatusSortComparisonUpdated);
            var ids = from Service s in Core.PluginManager.GetServiceEnumerator().ToArray<Service>()
                      select s.Id;
            LinkedServiceIds = ids.ToArray<string>();
        }

        void StatusServerSorts_StatusSortComparisonUpdated()
        {
            containStatus.Sort(new Comparison<XStatus>(Cores.StatusManager.StatusServerSorts.StatusSortComparison));
        }

        public void Dispose()
        {
            Core.StatusManager.OnXStatusRegistered -= registered;
            Core.StatusManager.OnXStatusRemoved -= removed;
            containStatus.Clear();
            registered = null;
            removed = null;
            containStatus = null;
        }

        void  StatusManager_RegistStatus(IEnumerable<XStatus> xstatuses)
        {
            bool adf = false;
            List<XStatus> newx = new List<XStatus>();
            foreach (var xs in xstatuses)
            {
                if (ContainSearchData == null || ContainSearchData.IsMatched(xs.BaseStatus))
                {
                    containStatus.Add(xs);
                    adf = true;
                    newx.Add(xs);
                }
            }
            containStatus.Sort(new Comparison<XStatus>(Cores.StatusManager.StatusServerSorts.StatusSortComparison));
            if (adf && ContainStatusChanged != null)
            {
                ContainStatusChanged.Invoke(this, new EventArgs());
                if (!this.UnNotify)
                    Core.NotificationManager.SetNotificate(newx);
            }
        }

        void StatusManager_RemoveStatus(IEnumerable<XStatus> xstatuses)
        {
            bool adf = false;
            foreach (var xs in xstatuses)
            {
                foreach (var s in containStatus)
                {
                    if (xs == s)
                    {
                        containStatus.Remove(s);
                        adf = true;
                        break;
                    }
                }
            }
            if (adf && ContainStatusChanged != null)
                ContainStatusChanged.Invoke(this, new EventArgs());
        }

        private string nameBuffer = null;
        /// <summary>
        /// Tab name (equals Parent.Name)
        /// </summary>
        public string Name
        {
            get
            {
                if (parentTabItem == null)
                    return nameBuffer;
                else
                    return parentTabItem.Name;
            }
            set
            {
                if (parentTabItem == null)
                    nameBuffer = value;
                else
                    parentTabItem.Name = value;
            }
        }

        /// <summary>
        /// Unnotify state
        /// </summary>
        public bool UnNotify { get; set; }

        /// <summary>
        /// Locking state in this tab
        /// </summary>
        public bool Locked { get; set; }

        /// <summary>
        /// Search data cluster which be contained this tab.
        /// </summary>
        public SearchDataCluster ContainSearchData { get; set; }

        /// <summary>
        /// Linked Service id
        /// </summary>
        public String[] LinkedServiceIds { get; set; }

    }
}
